CDKを使って既存S3バケットのPUTイベントをトリガーにLambda関数を実行しようとしたらハマった話
こんにちは、AWS事業本部@福岡オフィスのべこみん(@beco_minn)です。
最近はCDK楽しいマンになってます。
さて、皆さんは「CDKを使って、既存S3バケットのイベントドリブンでLambda関数を実行したいな〜」と思ったことはないですか?
今回は僕がそう思った時にハマったことを共有します。
ちなみに本記事で使用している言語はTypeScriptです。
いきなりまとめ
- CDKを使って既存S3バケットのイベントをトリガーにLambda関数をキックしたい時は、S3側のイベント通知機能を使おう
s3.Bucket.AddNotification
を使うlambda.Function.addEventSource
はS3バケットを新規作成する場合にしか対応してない
はじめに
今回やりたいことはこんなイメージ
S3のイベントドリブンでLambda関数を実行するパターンは以下の2パターンが考えられるかと思います。
- S3のイベント通知を使う
- Lambdaにイベントソースを追加する
僕は後者の『Lambdaにイベントソースを追加する』でいけるだろ〜と思ってやってみました。
Lambdaにイベントソースを追加するにはこの S3EventSource
クラスを使用します。
lambda.Function.addEventSource
でハマった
早速サンプルコードを真似して書いてみるとこんなエラーが。
型 'IBucket' の引数を型 'Bucket' のパラメーターに割り当てることはできません。 型 'IBucket' には 型 'Bucket' からの次のプロパティがありません: autoCreatePolicy, lifecycleRules, metrics, cors、32 など。
どうやらS3EventSourceで指定するバケットの型は Bucket
じゃないとダメらしい。
既存バケットを取得する方法としては、s3.Bucketの fromBucketArn()
、fromBucketAttributes()
、 fromBucketName()
があるのですが、これらの戻り値の型はどれも IBucket
なんです。。。
Google先生と睨めっこしてたらこんなissueがありました。
S3EventSource should take IBucket instead of Bucket #4323 - https://github.com/aws/aws-cdk/issues/4323
どうやら既存バケットを使う場合は s3.Bucket.AddNotification
を使うのが正解っぽい。
【解決方法】 s3.Bucket.AddNotification
ということで、既存バケットのイベントドリブンでLambda関数を実行したい場合は s3.Bucket.AddNotification
を使いましょう。
// Lambda Function const target_function = new Function(this, "sumpleFunc", { code: new AssetCode("resources"), handler: "index.handler", runtime: Runtime.NODEJS_16_X, functionName: "sumple_function", timeout: Duration.seconds(60) }); // 既存のS3バケットを取得 const existing_bucket = Bucket.fromBucketArn( this, 'sumple-bucket-20220630-becominn', 'arn:aws:s3:::sumple-bucket-20220630-becominn' ) // S3Notificationを設定 existing_bucket.addEventNotification( EventType.OBJECT_CREATED_PUT, new LambdaDestination(target_function) )
サンプルのソースコードも置いておきます。
最後に
今回の解決方法はどちらかといえば妥協案のようなものですが、やりたいことは達成出来ました。
私は最近CDKを触り始めた初心者なので、今回のように型でハマることが多いですね。(ただ型があるのは嬉しい)
本記事がどなたかのお役に立てれば幸いです。
以上、べこみんでした。